"""
Watermarking by using Logarithmic quantification
"""
#
# logarithmic_quantification.py
#
# Copyright (C) 2012 Robert Buj Gelonch
# Copyright (C) 2012 David Megias Jimenez
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
__author__ = "Robert Buj Gelonch, and David Megias Jimenez"
__copyright__ = "Copyright 2012, Robert Buj Gelonch and David Megias Jimenez"
__credits__ = ["Robert Buj Gelonch", "David Megias Jimenez"]
__license__ = "GPL"
__version__ = "3"
__maintainer__ = "Robert Buj"
__email__ = "rbuj@uoc.edu"
__status__ = "Development"
__docformat__ = 'plaintext'

from itertools import cycle

from numpy import array
from numpy import copysign
from numpy import fix
from numpy import int16
from numpy import sign
from numpy import where
from numpy.lib.scimath import logn
from uoc.wave.watermark.schemes.generic import generic_detection_function as D_generic

def embedding_function(S, w, P_watermarking_sheme):
    """
    Embed the watermark within the original audio signal by using
    the logarithmic quantification. Add the watermark in the
    exponent on applying the logarithm of a given base by using
    the LSB watermark scheme. Then, rebuild the sample applying
    the exponentoal function
    """
    S_fixed = array(S)
    # set the minor allowed value in the logarithmic quantification
    base = P_watermarking_sheme['max_value'] ** (1.0 / P_watermarking_sheme['steps'])
    min_value = base ** (1 - P_watermarking_sheme['steps'])
    for i in where(abs(S_fixed) < min_value)[0]:
        if S_fixed[i] != 0:
            S_fixed[i] = copysign(min_value, numpy.sign(S[i]))
        else:
            S_fixed[i] = min_value
    exp = fix(logn(base, abs(S_fixed)))
    # loop variables
    w_cycle_iterator = cycle(w)
    num_frames = int(fix(len(S_fixed) / P_watermarking_sheme['frame_size']))
    # loop: work within the splitted signal in blocks
    for frame in range(num_frames):
        start = frame * P_watermarking_sheme['frame_size']
        end = start + P_watermarking_sheme['frame_size']
        if w_cycle_iterator.next() == 1:
            exp[start:end] = exp[start:end] + (sign(exp[start:end]) * 0.5)
    # last samples
    start = end
    if (num_frames * P_watermarking_sheme['frame_size']) != len(S_fixed):
        if w_cycle_iterator.next() == 1:
            exp[start:] = exp[start:] + (sign(exp[start:]) * 0.5)
    sp = base ** exp
    s = copysign(sp, sign(S_fixed))
    return s

def retrieval_function(s, P_watermarking_sheme):
    """
    Return the embedded watermark message within the watermarked
    audio signal
    """
    # logarithmic quantification
    base = P_watermarking_sheme['max_value'] ** (1.0 / P_watermarking_sheme['steps'])
    exp = logn(base, abs(s))
    # extract the watermark
    R = (abs(exp) % 1) > 0.4
    return R.astype(int16)

def detection_function(s, w, P_watermarking_sheme):
    """
    Evaluate whether the watermarked signal, it contains the
    watermarked message
    """
    return D_generic(s, w, P_watermarking_sheme)

